import React, { Component } from 'react'

import { FormattedMessage, Dispatch, connect } from 'umi'
import { GridContent } from '@ant-design/pro-layout'
import { Menu } from 'antd'
import Skeleton from '@ant-design/pro-skeleton'
import BaseView from './components/base'
import BindingView from './components/binding'
import { CurrentUser } from './data.d'
import NotificationView from './components/notification'
import SecurityView from './components/security'
import styles from './style.less'

const { Item } = Menu

interface SettingsProps {
    dispatch: Dispatch
    currentUser: CurrentUser
}

type SettingsStateKeys = 'base' | 'security' | 'binding' | 'notification'
interface SettingsState {
    mode: 'inline' | 'horizontal'
    menuMap: {
        [key: string]: React.ReactNode
    }
    selectKey: SettingsStateKeys
}

class Settings extends Component<SettingsProps, SettingsState> {
    main: HTMLDivElement | undefined = undefined

    constructor(props: SettingsProps) {
        super(props)
        const menuMap = {
            base: (
                <FormattedMessage id="accountandsettings.menuMap.basic" defaultMessage="Basic Settings" />
            ),
            security: (
                <FormattedMessage
                    id="accountandsettings.menuMap.security"
                    defaultMessage="Security Settings"
                />
            ),
            binding: (
                <FormattedMessage
                    id="accountandsettings.menuMap.binding"
                    defaultMessage="Account Binding"
                />
            ),
            notification: (
                <FormattedMessage
                    id="accountandsettings.menuMap.notification"
                    defaultMessage="New Message Notification"
                />
            ),
        }
        this.state = {
            mode: 'inline',
            menuMap,
            selectKey: 'base',
        }
    }

    componentDidMount() {
        const { dispatch } = this.props
        dispatch({
            type: 'accountAndsettings/fetchCurrent',
        })
        window.addEventListener('resize', this.resize)
        this.resize()
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.resize)
    }

    getMenu = () => {
        const { menuMap } = this.state
        return Object.keys(menuMap).map((item) => <Item key={item}>{menuMap[item]}</Item>)
    }

    getRightTitle = () => {
        const { selectKey, menuMap } = this.state
        return menuMap[selectKey]
    }

    selectKey = (key: SettingsStateKeys) => {
        this.setState({
            selectKey: key,
        })
    }

    resize = () => {
        if (!this.main) {
            return
        }
        requestAnimationFrame(() => {
            if (!this.main) {
                return
            }
            let mode: 'inline' | 'horizontal' = 'inline'
            const { offsetWidth } = this.main
            if (this.main.offsetWidth < 641 && offsetWidth > 400) {
                mode = 'horizontal'
            }
            if (window.innerWidth < 768 && offsetWidth > 400) {
                mode = 'horizontal'
            }
            this.setState({
                mode,
            })
        })
    }

    renderChildren = () => {
        const { selectKey } = this.state
        switch (selectKey) {
            case 'base':
                return <BaseView />
            case 'security':
                return <SecurityView />
            case 'binding':
                return <BindingView />
            case 'notification':
                return <NotificationView />
            default:
                break
        }

        return null
    }

    render() {
        const { currentUser } = this.props
        if (!currentUser.userId) {
            return <Skeleton active type='list' list={1} />
        }
        const { mode, selectKey } = this.state
        return (
            <GridContent>
                <div
                    className={styles.main}
                    ref={(ref) => {
                        if (ref) {
                            this.main = ref
                        }
                    }}
                >
                    <div className={styles.leftMenu}>
                        <Menu
                            mode={mode}
                            selectedKeys={[selectKey]}
                            onClick={({ key }) => this.selectKey(key as SettingsStateKeys)}
                        >
                            {this.getMenu()}
                        </Menu>
                    </div>
                    <div className={styles.right}>
                        <div className={styles.title}>{this.getRightTitle()}</div>
                        {this.renderChildren()}
                    </div>
                </div>
            </GridContent>
        )
    }
}

export default connect(
    ({ accountAndsettings }: { accountAndsettings: { currentUser: CurrentUser } }) => ({
        currentUser: accountAndsettings.currentUser,
    }),
)(Settings)
